package com.alibaba.citrus.ots.platform.enhance.functions.diff.common.template;

import com.alibaba.citrus.ots.platform.enhance.functions.diff.common.constant.OrderStatusCompareWayEnum;
import com.alibaba.citrus.ots.platform.enhance.repository.model.diff.common.FieldCheckFailDTO;
import com.alibaba.citrus.ots.platform.enhance.repository.model.diff.common.FieldLineDTO;
import com.alibaba.citrus.ots.platform.enhance.repository.model.diff.common.OrderStatusFieldDTO;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * @author: qiaojiange
 * @create: 2022/01/19
 * @Description 请描述类的业务用途
 */
@Component
public class StandardTemplateDiff implements Check {

    /**
     * 日志
     */
    private Log log = Log.getLogger(StandardTemplateDiff.class);

    @Override
    public Result<String> check(Set<String> standardFieldSet, Map<String, FieldLineDTO> map, Set<String> ignoreFieldSet) {
        if (MapUtils.isEmpty(map)) {
            return Result.fail("", "和标准模板对比数据为空，校验不通过！");
        }

        if (CollectionUtils.isEmpty(standardFieldSet)) {
            return Result.fail("", "标准字段数据集不能为空！");
        }

        Map<String, FieldLineDTO> newMap = new HashMap<>();
        newMap.putAll(map);

        //和 set 中的数据进行对比
        for (String field : standardFieldSet) {
//             1. 忽略列表不为空的情况下，进行部分校验
            if (CollectionUtils.isNotEmpty(ignoreFieldSet)) {
                //如果不在忽略列表中字段，需要校验是否为空，在忽略列表中的字段就不用校验了
                if (!ignoreFieldSet.contains(field) && StringUtils.isBlank(newMap.get(field).getFieldValue())) {
                    return Result.fail("", "字段：" + field + "不能为空！");
                }
            } else {
//              2. 忽略列表为空的情况下，全部进行校验
                if (Objects.isNull(newMap.get(field))) {
                    return Result.fail("", "该字段：" + field + "在对象上不存在！");
                }
                if (Objects.nonNull(newMap.get(field)) && StringUtils.isBlank(newMap.get(field).getFieldValue())) {
                    return Result.fail("", "字段：" + field + "不能为空！");
                }
            }
        }
        return Result.success("标准模板校验通过！");
    }


    /**
     * 字段比对
     *
     * @param standardFieldSet
     * @param obj
     * @param clazz
     * @return
     */
    @Override
    public Result<String> checkForStatus(Set<OrderStatusFieldDTO> standardFieldSet, Object obj, Class<?> clazz, Set<String> ignoreFieldSet) {

        List<FieldCheckFailDTO> checkFailDTOList = new ArrayList<>();
        if (Objects.isNull(obj)) {
            return Result.fail("", "和标准模板对比数据为空，校验不通过！");
        }

        if (CollectionUtils.isEmpty(standardFieldSet)) {
            return Result.fail("", "标准字段数据集不能为空！");
        }
        //和 set 中的数据进行对比
        for (OrderStatusFieldDTO orderStatusFieldDTO : standardFieldSet) {

            String fieldName = orderStatusFieldDTO.getTableField();

            //获取DB上字段值
            Object fieldValue = null;
            try {

                if (org.apache.commons.lang.StringUtils.contains(fieldName, "features") && org.apache.commons.lang.StringUtils.contains(fieldName, ".")) {
                    String featuresKey = fieldName.split("\\.")[1];
                    Field featuresField = clazz.getDeclaredField("features");
                    featuresField.setAccessible(true);
                    String featuresValue = (String) featuresField.get(obj);
                    fieldValue = JSONObject.parseObject(featuresValue).get(featuresKey);
                } else {
                    Field field = clazz.getDeclaredField(fieldName);
                    field.setAccessible(true);
                    fieldValue = field.get(obj);
                }


            } catch (NoSuchFieldException | IllegalAccessException e) {
                log.error("获取字段异常:" + fieldName, e);
                FieldCheckFailDTO fieldCheckFailDTO = FieldCheckFailDTO.of(fieldName, "获取字段异常");
                checkFailDTOList.add(fieldCheckFailDTO);
            }

//             1. 忽略列表不为空的情况下，进行部分校验
            if (CollectionUtils.isNotEmpty(ignoreFieldSet)) {
                //如果不在忽略列表中字段，需要校验是否为空，在忽略列表中的字段就不用校验了
                if (!ignoreFieldSet.contains(fieldName) && Objects.isNull(fieldValue)) {
                    FieldCheckFailDTO fieldCheckFailDTO = FieldCheckFailDTO.of(fieldName, "字段：" + fieldName + "不能为空！");
                    checkFailDTOList.add(fieldCheckFailDTO);
                }
            } else {

                //获取字段的校验方式
                String compareWay = orderStatusFieldDTO.getCompareWay();

                //空
                if (OrderStatusCompareWayEnum.NULL.getFieldCode().equals(compareWay)) {
                    if (Objects.nonNull(fieldValue)) {
                        FieldCheckFailDTO fieldCheckFailDTO = FieldCheckFailDTO.of(fieldName, "字段：" + "该字段：" + fieldName + "的值不能为非空！");
                        checkFailDTOList.add(fieldCheckFailDTO);
                    }
                }

                //非空
                if (OrderStatusCompareWayEnum.NOT_NULL.getFieldCode().equals(compareWay)) {
                    if (Objects.isNull(fieldValue)) {
                        FieldCheckFailDTO fieldCheckFailDTO = FieldCheckFailDTO.of(fieldName, "该字段：" + fieldName + "的值不能为空！");
                        checkFailDTOList.add(fieldCheckFailDTO);
                    }
                }
                //特定值
                if (OrderStatusCompareWayEnum.SPECIAL_VALUE.getFieldCode().equals(compareWay)) {
                    String specialValue = orderStatusFieldDTO.getFieldValue();

                    if (!specialValue.equals(fieldValue)) {
                        FieldCheckFailDTO fieldCheckFailDTO = FieldCheckFailDTO.of(fieldName, "该字段："
                                + fieldName + "的值不正确！" + "正确的值为:'" + specialValue
                                + "', 当前值为：'" + fieldValue+"'");
                        checkFailDTOList.add(fieldCheckFailDTO);
                    }
                }
            }
        }
        if (CollectionUtils.isEmpty(checkFailDTOList)) {

            return Result.success("标准模板校验通过！");
        }

        return Result.fail("", JSONObject.toJSONString(checkFailDTOList));
    }
}
